/*
 *  JFLAP - Formal Languages and Automata Package
 *
 *
 *  Susan H. Rodger
 *  Computer Science Department
 *  Duke University
 *  August 27, 2009

 *  Copyright (c) 2002-2009
 *  All rights reserved.

 *  JFLAP is open source software. Please see the LICENSE for terms.
 *
 */

package puf.m2.regular;

import java.io.Serializable;

public abstract class RegExp implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final String EPSILON = "\u03B5";

    /* Operators can be used in a regular expression */
    /** OR operator */
    public static final char OR = '+';
    /** MULTIPLY operator */
    public static final char STAR = '*';
    /** LEFT PARENTHESIS */
    public static final char LPAR = '(';
    /** RIGHT PARENTHESIS */
    public static final char RPAR = ')';
    /** COMMA used in tiles */
    public static final char COMMA = ',';
    /** SYNTACTIC INVERSE OPERATOR */
    public static final char INVERSE = '~';

    /** The string of the regular expression. */
    protected String string;

    /**
     * Instantiates a blank regular expression.
     */
    public RegExp() {
        this("");
    }

    /**
     * Instantiates a regular expression from the given string.
     *
     * @param string
     *            the string to treat as a regular expression
     */
    public RegExp(String string) {
        this.string = string;
    }

    /**
     * Instantiates a regular expression from another regular expression.
     *
     * @param expression
     *            the expression to copy
     */
    public RegExp(RegExp expression) {
        this(expression.toString());
    }

    /**
     * Returns the string representation of the object.
     *
     * @return the regular expression as string
     */
    public String toString() {
        return string;
    }

    /**
     * Checks if things are balanced or sufficient in a string.
     * Things here can be parentheses or commas (in case of tile)
     * @param str
     *      the string to check
     * @return
     *      if the things are balanced
     */
    protected abstract boolean areThingsBalanced(String str);

    /**
     * Returns the error checked string representation.
     *
     * @return the string version of the exception
     * @throws UnsupportedOperationException
     *             if the expression is not properly formed
     */
    public abstract String asCheckedString();

    /**
     * This handles serialization so that the reference, if it exists, is
     * resolved to a string rather than being stored itself.
     *
     * @param out
     *            the object output stream
     */
    private void writeObject(java.io.ObjectOutputStream out)
            throws java.io.IOException {
        // Force the reference to be resolved, and invalidated.
        toString();
        // Now we may call the default writer.
        out.defaultWriteObject();
    }

    /**
     * This handles deserialization so that the listener sets are reset to avoid
     * null pointer exceptions when one tries to add listeners to the object.
     *
     * @param in
     *            the input stream for the object
     */
    private void readObject(java.io.ObjectInputStream in)
            throws java.io.IOException, ClassNotFoundException {
        in.defaultReadObject();
    }

}
